package com.slf.demo1;

import java.io.*;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: shilvfa
 * @date: 2025-07-13 19:54
 * @email:shilfwh@163.com
 * @Description:
 */
public class 网盘期货_106金烨数据处理3 {
    //是否是分钟数据
//    private static final boolean isMinData = true;
//    private static final String  FilePath = "F:\\股指数据金烨\\106数据min提取";


    private static final boolean isMinData = false;
    private static final String  FilePath = "F:\\股指数据金烨\\106数据rec提取";

    private static final String OUTPUT_FILEPATH = "F:\\股指数据金烨\\输出";
    private static final String INPUT_FILEPATH_FUTURES = "F:\\股指数据金烨\\期货数据";

    //期货价格map,code,日期_时间,value是价格
    private static Map<String, Map<String, Double>> futuresMap = new HashMap<>();

    public static void main(String[] args) {
        //读取期货数据
        processFuturesData(INPUT_FILEPATH_FUTURES);
        //读取分钟数据
        Map<String, List<IndexCollectData>> map = readIndexDataFromDirectory(FilePath);


        //TODO 便利map,输出文件
        for (String code : map.keySet()) {
            List<IndexCollectData> indexCollectDataList = map.get(code);
            if (indexCollectDataList.isEmpty()) {
                System.out.println("没有数据,不输出文件");
                continue;
            }
            System.out.println("code:" + code + " size:" + indexCollectDataList.size());
            //文件名是list中第一个数据的日期_最后一个数据的日期
            String fileName = code + "_" + indexCollectDataList.get(0).getDate() + "_" + indexCollectDataList.get(indexCollectDataList.size() - 1).getDate()+(isMinData?"_1min":"_15s") + ".csv";
            //输出文件
            printStockCollectData2Csv(indexCollectDataList, OUTPUT_FILEPATH + File.separator + fileName);
        }

    }

    private static void processFuturesData(String inputFilepathFutures) {
        File dir = new File(inputFilepathFutures);

        // 检查目录是否存在
        if (!dir.exists() || !dir.isDirectory()) {
            System.err.println("目录不存在或不是有效目录: " + inputFilepathFutures);
            return;
        }

        // 获取目录下所有CSV文件
        File[] futruesDirs = dir.listFiles();
        if (futruesDirs == null || futruesDirs.length != 4) {
            System.err.println("missing files in directory: " + inputFilepathFutures);
            return;
        }

        for(File futruesDir : futruesDirs){
            String futruesName = futruesDir.getName();
            for (File dateDir : futruesDir.listFiles()) {
                if (!dateDir.isDirectory()) {
                    continue;
                }
                String date = dateDir.getName();
                for (File file : dateDir.listFiles()) {
                    Map<String, Double> oneDayMap = FuturesDataProcessor.createPriceMap(file.getAbsolutePath());
                    //合并到futuresMap
                    futuresMap.computeIfAbsent(futruesName, k -> new HashMap<>()).putAll(oneDayMap);
                }
            }
        }


    }

    public static Map<String, List<IndexCollectData>> readIndexDataFromDirectory(String directoryPath) {
        Map<String, List<IndexCollectData>> resultMap = new HashMap<>();
        File dir = new File(directoryPath);

        // 检查目录是否存在
        if (!dir.exists() || !dir.isDirectory()) {
            System.err.println("目录不存在或不是有效目录: " + directoryPath);
            return resultMap;
        }

        // 获取目录下所有CSV文件
        File[] files = dir.listFiles((d, name) -> name.toLowerCase().endsWith(".csv"));
        if (files == null || files.length == 0) {
            System.err.println("目录中没有CSV文件: " + directoryPath);
            return resultMap;
        }

        for (File file : files) {
            try (BufferedReader br = new BufferedReader(new FileReader(file))) {
                String line;

                IndexCollectData preData= null;//TODO


                while ((line = br.readLine()) != null) {
                    String[] fields = line.split(",");
                    if (fields.length < 10) {
                        System.err.println("数据行字段不足10个: " + line);
                    }

                    try {
                        // 解析CSV字段
                        String code = fields[0].trim();
                        // 从datetime字段分离日期和时间 (格式: yyyyMMddHHmmssSS)
                        String date = fields[9].substring(0, 8);
                        // HHmmss
                        String time = fields[1].substring(0,fields[1].length()-3);

                        long bigAmount =Long.parseLong(fields[3].trim());
                        long sumAmount = Long.parseLong(fields[4].trim());

                        double indexPrice = Double.parseDouble(fields[2].trim());
                        double futuresPrice = futuresMap.get(getFuturesCode(code)).get( date +"_"+ fillZero(time)) ;//TODO
                        double filed1 = 0;
                        double filed2 = 0;

                        long totalAskAmount = Long.parseLong(fields[6].trim());//盘口总卖单（不含涨跌停）
                        long totalBidAmount = Long.parseLong(fields[5].trim());//盘口总买单（不含涨跌停）
                        double totalBidRate = (double) totalBidAmount / (totalAskAmount + totalBidAmount);//买入比率

                        int isLastTradeDate = isThirdFriday(date);

                        int riseNum = 0;//成分股上涨个数
                        int fallNum = 0;//成分股下跌个数
                        double filed3 = 0;//预留字段

                        long bsBigSumAmount = 0; //  // 未使用的字段设为默认值

                        IndexCollectData data = new IndexCollectData(code, date, time, bigAmount, sumAmount,
                                indexPrice, futuresPrice, filed1, filed2, totalAskAmount, totalBidAmount,
                                totalBidRate, isLastTradeDate, riseNum, fallNum, filed3, bsBigSumAmount);

                        //复制一份数据,用于备份
                        IndexCollectData copyData = new IndexCollectData(data);

                        if (!isMinData && preData != null && preData.getDate().equals(data.getDate())) {
                                data.setBigAmount(data.getBigAmount() - preData.getBigAmount());
                                data.setSumAmount(data.getSumAmount() - preData.getSumAmount());
                                data.setBsBigSumAmount(data.getBsBigSumAmount() - preData.getBsBigSumAmount());
                        }

                        preData = copyData;//更新preData
                        resultMap.computeIfAbsent(code, k -> new ArrayList<>()).add(data);

                    } catch (Exception e) {
                        System.err.println("解析数据行失败: " + line + " - " + e.getMessage());
                    }
                }
            } catch (IOException e) {
                System.err.println("处理文件时出错: " + file.getName() + " - " + e.getMessage());
            }
        }
        return resultMap;
    }

    private static String getFuturesCode(String code) {
        if (code.equals("000016")) {
            return "IH";
        }else if (code.equals("000300")) {
            return "IF";
        }else if (code.equals("000905")) {
            return "IC";
        }else if (code.equals("000852")) {
            return "IM";
        }
        return null;
    }

    private static String fillZero(String time) {
        if (time.length() == 5) {
            return "0" + time;
        }
        return time;
    }

    public static int isThirdFriday(String dateStr) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        try {
            LocalDate date = LocalDate.parse(dateStr, formatter);
            return checkThirdFriday(date) ? 1 : 0;
        } catch (DateTimeParseException e) {
            return 0; // 格式错误直接返回0
        }
    }

    private static boolean checkThirdFriday(LocalDate date) {
        // 计算当月的第三个星期五
        LocalDate thirdFriday = date.withDayOfMonth(1) // 当月第一天
                .with(TemporalAdjusters.nextOrSame(DayOfWeek.FRIDAY)) // 第一个星期五
                .plusWeeks(2); // 加两周得到第三个星期五
        return date.isEqual(thirdFriday);
    }

    private static void printStockCollectData2Csv(List<IndexCollectData> indexCollectDataList, String fileName) {
        BufferedWriter bw = null;
        try {
            bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName)));
            for (IndexCollectData d : indexCollectDataList) {
                StringBuilder sb = new StringBuilder();
                sb.append(d.getDate()).append(",").
                        append(d.getTime()).append(",").
                        append(d.getBigAmount()).append(",").
                        append(d.getSumAmount()).append(",").
                        append(d.getIndexPrice()).append(",").
                        append(d.getFuturesPrice()).append(",").
                        append(d.getFiled1()).append(",").
                        append(d.getFiled2()).append(",").
                        append(d.getTotalAskAmount()).append(",").
                        append(d.getTotalBidAmount()).append(",").
                        append(d.getTotalBidRate()).append(",").
                        append(d.getIsLastTradeDate()).append(",").
                        append(d.getRiseNum()).append(",").
                        append(d.getFallNum()).append(",").
                        append(d.getFiled3()).append(",").
                        append(d.getBsBigSumAmount()).append(",");

                bw.write(sb.toString());
                bw.newLine();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bw != null) {
                try {
                    bw.flush();
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
